<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>State Hook</title>
    <style></style>
</head>

<body>
    <div id="test"></div>
    <!-- 引入react核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入react Dom库 用于支持 react操作dom-->
    <script src="../js/react-dom.development.js"></script>
    <!-- 引入babel 用于将 jsx 转为 js -->
    <script src="../js/babel.min.js"></script>
    <div>
        <h1>可以吧 useEffect Hook 看做 componentDidMount,componentDidUpdate
            和 componentWillUnmount这三个函数的组合
        </h1>
        <p>1.如果第二个参数为空数组，useEffect 相当于类组件里面componentDidMount,
            页面渲染完成后，会执行一次useEffect。再次执行按钮改变state，页面重新渲染后，
            useEffect不会执行。
            <div>
                useEffect(() => {
                console.log("我只会在组件初次挂载完成后执行");
                }, []);
            </div>
        </p>
        <p>
            2.如果不传第二个参数，useEffect会在初次渲染和每次更新时，都会执行，相当于
            类组件中的componentDidUpdate。初次渲染时，会执行一次useEffect,当点击按
            钮时，改变了state,页面渲染，useEffect都会执行。
            <div>
                useEffect(() => {
                console.log("我会在初次组件挂载完成后以及重新渲染时执行");
                });
            </div>
        </p>
        <p>
            3.使用useEffect实现componentWillUnmount,
            effect返回一个函数，React将会在执行清除操作时调用它。
            注意：这里不只是组件销毁时才会打印 “执行清除操作”，每次重新渲染时
            也会都执行。
            <div>
                useEffect(() => {
                console.log("订阅一些事件");
                return () => {
                console.log("执行清除操作")
                }
                },[]);
            </div>
        </p>
        <p>
            4.控制useEffect的执行，点击按钮时会打印，因为 useEffect的
            第二个参数的数组里面依赖是count，只有count发送改变时，useEffect
            才会执行，如果数组中多个元素，即使只有一个元素发生变化，react也会执行effect
            <div>
                useEffect(() => {
                console.log("我只会在cout变化时执行");
                }, [count]);
            </div>
        </p>
        <p>
            5.使用Hook 其中一个目的 就是要解决class中生命周期函数经常包含不相关
            的逻辑，但又把相关逻辑分离到了几个不同方法中的问题。
            Hook允许我们按照代码的用途分离他们，而不是像生命周期函数那样，
            React按照effect声明的顺序依次调用组件中的每一个effect
            <div>
                useEffect(() => {
                // 逻辑一
                });
                useEffect(() => {
                // 逻辑二
                });
                useEffect(() => {
                // 逻辑三
                });
            </div>
        </p>
        <p>
            useEffect中使用异步函数,useEffect是不能直接使用
            async await 语法糖的，useEffect的回调参数返回的是
            一个清除副作用的 clean-up函数。因此无法返回promise,
            更无法使用 async / await
            <span>
                那应该如何让 useEffect 支持 async / await 呢？
            </span>
            <div>
                <span>方法一</span>
                <div>
                    useEffect(()=>{
                    ( async function getDatas(){
                    await getData()
                    })()
                    },[])
                </div>
            </div>
            <div>
                <span>方法二</span>
                <div>
                    useEffect(()=>{
                    const getDatas = async () => {
                    const data = await getData()
                    setData(data)
                    }
                    getDatas()
                    },[])
                </div>
            </div>
        </p>
    </div>
    <!-- 使用babel 转译jsx -->
    <script type="text/babel">
        function Demo() {
        // 数组结构  到一个是参数  第二个是方法
        const [count, setCount] = React.useState(0);
        // 可以传递两个参数，就一个参数全部都监测，第二个参数写上表示谁也不监测，也可以在空数组里面写conut 表示监测count
        React.useEffect(() => {
          let timer = setInterval(() => {
            setCount((count) => {
              return count + 1;
            });
          }, 1000);
          // 这里返回的函数相当于将要卸载生命周期
          return () => {
            clearInterval(timer);
          };
        }, [count]);

        function unmount() {
          ReactDOM.unmountComponentAtNode(document.getElementById("test"));
        }

        function add() {
          // 第一种写法
          // setCount(count + 1);
          //   第二种写法
          setCount((count) => {
            return count + 1;
          });
        }
        return (
          <div>
            <h1>{count}</h1>
            <button onClick={add}>+1</button>
            <button onClick={unmount}>卸载组件</button>
          </div>
        );
      }
      ReactDOM.render(<Demo />, document.getElementById("test"));
    </script>
</body>

</html>